#include "gui_button.h"
#include"gui_signal.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

static int gui_button_create_signals(gui_spirit_t *spirit)
{
    assert(!gui_signal_create(spirit, "button_press"));
    assert(!gui_signal_create(spirit, "button_release"));
    assert(!gui_signal_create(spirit, "enter_notify"));
    assert(!gui_signal_create(spirit, "leave_notify"));
}

gui_spirit_t *gui_button_create()
{
    gui_button_t *button = malloc(sizeof(gui_button_t));
    if (!button)
        return NULL;
    button->status = GUI_BUTTON_IDLE;
    button->color_idle = GUI_WHITE;
    button->color_click = GUI_RGB_SUB(button->color_idle, 0x20, 0x20, 0x20);
    button->color_touch = GUI_RGB_SUB(button->color_idle, 0x40, 0x40, 0x40);
    button->color_disable = GUI_RGB(0x80, 0x80, 0x80);
    button->disable = 0;
    button->flags = 0;
    list_init(&button->list); //init list object

    gui_spirit_t *spirit = &button->spirit;
    gui_spirit_init(spirit, 0, 0, GUI_BUTTON_WIDTH_DEFAULT, GUI_BUTTON_HEIGHT_DEFAULT);
    gui_spirit_set_type(spirit, GUI_SPIRIT_TYPE_BUTTON);

    spirit->style.border_color = GUI_GRAY;
    spirit->style.background_color = button->color_idle;
    spirit->style.font_color = GUI_BLACK;
    spirit->style.font_align = GUI_ALIGN_CENTER;

    if (gui_button_create_signals(spirit) < 0)
    {
        gui_spirit_cleanup(spirit);
        free(button);
        return NULL;
    }
    return spirit;
}

gui_spirit_t *gui_button_create_with_label(char *label)
{
    gui_spirit_t *spirit = gui_button_create();
    if (!spirit)
        return NULL;
    if (gui_spirit_set_text(spirit, label))
    {
        gui_spirit_destroy(spirit);
        return NULL;
    }
    gui_spirit_auto_size(spirit);
    return spirit;
}


int gui_button_set_disable(gui_button_t *button)
{
    if (!button)
        return -1;
    if (button->disable)
        return -1;
    button->disable = 1;
    button->status = GUI_BUTTON_IDLE;
    button->spirit.style.background_color = button->color_disable;
    if (button->spirit.style.font_color)
        button->spirit.style.font_color = GUI_RGB_ADD(button->color_disable, 0x40, 0x40, 0x40);
    gui_spirit_show(&button->spirit);
    return 0;
}

int gui_button_set_enable(gui_button_t *button)
{
    if (!button)
        return -1;
    if (!button->disable)
        return -1;
    button->disable = 0;
    button->status = GUI_BUTTON_IDLE;
    button->spirit.style.background_color = button->color_idle;
    if (button->spirit.style.font_color)
        button->spirit.style.font_color = GUI_BLACK;
    gui_spirit_show(&button->spirit);
    return 0;
}

void gui_button_change_status(gui_button_t *button, gui_button_status_t status)
{
    //don't reapt change button status 
    if (button->status == status)
        return;

    button->status=status; //modify current status

    gui_spirit_t *spirit=&button->spirit;
    switch (status)
    {
    case GUI_BUTTON_IDLE:
        if (spirit->style.background_color != GUI_COLOR_NONE)
            spirit->style.background_color = button->color_idle;
        break;
    case GUI_BUTTON_TOUCH:
        if (spirit->style.background_color != GUI_COLOR_NONE)
            spirit->style.background_color = button->color_touch;
        break;
    case GUI_BUTTON_CLICK:
        if (spirit->style.background_color != GUI_COLOR_NONE)
            spirit->style.background_color = button->color_click;
        break;
    default:
        break;
    }
    gui_spirit_show(spirit);
}

void gui_button_set_title(gui_button_t *button,char *text)
{
    if(!button)
        return ;
    gui_spirit_hide(&button->spirit);
    gui_spirit_set_text(&button->spirit,text);    
    if(!(button->flags&GUI_BUTTON_SIZE_FIXED))
        gui_spirit_auto_size(&button->spirit);
    gui_spirit_show(&button->spirit);
}

void gui_button_set_size(gui_button_t *button,int width,int height)
{   
    if(!(button->flags&GUI_BUTTON_SIZE_FIXED))
    {
        gui_spirit_hide(&button->spirit);
        gui_spirit_reset_size(&button->spirit,width,height);
        gui_spirit_show(&button->spirit);
    }
}

void gui_button_set_size_fixed(gui_button_t *button,int fixed)
{
    if(!button)
        return;

    if(fixed)
        button->flags|=GUI_BUTTON_SIZE_FIXED;
    else 
        button->flags&=GUI_BUTTON_SIZE_FIXED;
}